﻿using System;

namespace LAPI.Business.Gestores
{
    /// <summary>
    /// Clase que implementa funciones para gestionar operaciones sobre la entidad de base de datos 'Deportes'
    /// </summary>
    public class GestorDeportes
    {
        /// <summary>
        /// Logger de la clase
        /// </summary>
        private LAPI.Core.Logging.ILogger logger;

        /// <summary>
        /// Constructor
        /// </summary>
        public GestorDeportes()
        {
            logger = LAPI.Core.Logging.LoggerFactory.CreateLogger(type: typeof(GestorDeportes));
        }

        #region Getter
        /// <summary>
        /// Método para obtener un listado de todos los deportes (activos y no activos)
        /// </summary>
        /// <returns>Una colección del modelo con todos los deportes</returns>
        /// <seealso cref="Deporte"/>
        /// <seealso cref="GestorBBDD"/>
        public System.Collections.Generic.List<LAPI.Data.Model.Deporte> ObtenerTodos()
        {
            System.Text.StringBuilder sql = new System.Text.StringBuilder();
            LAPI.Data.GestorBBDD oBBDD = LAPI.Data.GestorBBDDFactory.getGestorBBDD();
            System.Collections.Generic.List<LAPI.Data.Model.Deporte> result;

            sql.Append("Select ");
            sql.Append(LAPI.Data.Model.Deporte.Columns);
            sql.Append(" from ");
            sql.Append(LAPI.Data.Model.Deporte.Table);

            try
            {
                oBBDD.Abrir();
                result = LAPI.Data.Model.Deporte.toModel(oBBDD.Select(sql.ToString()));
                oBBDD.CerrarParcial();
                return result;
            }
            catch (Exception ex)
            {
                oBBDD.Cerrar();
                logger.Error(message: ex.Message, exception: ex);
                return null;
            }           
        }

        /// <summary>
        /// Método para obtener un listado de todos los deportes activos
        /// </summary>
        /// <returns>Una colección del modelo con todos los deportes</returns>
        /// <seealso cref="Deporte"/>
        /// <seealso cref="GestorBBDD"/>
        public System.Collections.Generic.List<LAPI.Data.Model.Deporte> ObtenerActivos()
        {
            System.Text.StringBuilder sql = new System.Text.StringBuilder();
            LAPI.Data.GestorBBDD oBBDD = LAPI.Data.GestorBBDDFactory.getGestorBBDD();
            System.Collections.Generic.List<LAPI.Data.Model.Deporte> result;

            sql.Append("Select ");
            sql.Append(LAPI.Data.Model.Deporte.Columns);
            sql.Append(" from ");
            sql.Append(LAPI.Data.Model.Deporte.Table);
            sql.Append(" where activo = 1 ");

            try
            {
                oBBDD.Abrir();
                result = LAPI.Data.Model.Deporte.toModel(oBBDD.Select(sql.ToString()));
                oBBDD.CerrarParcial();
                return result;
            }
            catch (Exception ex)
            {
                oBBDD.Cerrar();
                logger.Error(message: ex.Message, exception: ex);
                return null;
            }
        }

        /// <summary>
        /// Método para obtener los datos de los deportes que corresponde a un centro deportivo, sabiendo su identificador único
        /// </summary>
        /// <param name="IdCentroDeportivo">Int con el identificador único del centro deportivo</param>
        /// <returns>Una colección del modelo con todos los deportes</returns>
        /// <seealso cref="Deporte"/>
        /// <seealso cref="GestorBBDD"/>
        public System.Collections.Generic.List<LAPI.Data.Model.Deporte> ObtenerPorCentroDeportivo(Int32 IdCentroDeportivo)
        {
            System.Text.StringBuilder sql = new System.Text.StringBuilder();
            LAPI.Data.GestorBBDD oBBDD = LAPI.Data.GestorBBDDFactory.getGestorBBDD();
            System.Collections.Generic.List<LAPI.Data.Model.Deporte> result;

            sql.Append("Select ");
            sql.Append(" deportes.id_deportes, deportes.descripcion, deportes.color ");
            sql.Append(" from ");
            sql.Append(" PISTA, DEPORTES, DEPORTESPISTA ");
            sql.Append(" where PISTA.id_centrodeportivo = " + IdCentroDeportivo);
            sql.Append("   and DEPORTESPISTA.id_pista = PISTA.id_pista ");
            sql.Append("   and DEPORTESPISTA.id_deportes = deportes.id_deportes ");
            sql.Append("   and PISTA.activo = 1");
            sql.Append("   and DEPORTESPISTA.activo = 1");
            sql.Append(" group by deportes.id_deportes, deportes.descripcion, deportes.color ");

            try
            {
                oBBDD.Abrir();
                result = LAPI.Data.Model.Deporte.toModel(oBBDD.Select(sql.ToString()));
                oBBDD.CerrarParcial(); 
                return result;
            }
            catch (Exception ex)
            {
                oBBDD.Cerrar();
                logger.Error(message: ex.Message, exception: ex);
                return null;
            }
        }

        /// <summary>
        /// Método para obtener los datos de un deporte, sabiendo su identificador único
        /// </summary>
        /// <param name="IdDeporte">Int con el identificador único del Deporte</param>
        /// <returns>modelo Deporte con los datos</returns>
        /// <seealso cref="Deporte"/>
        /// <seealso cref="GestorBBDD"/>
        public LAPI.Data.Model.Deporte ObtenerPorID(Int32 IdDeporte)
        {
            System.Text.StringBuilder sql = new System.Text.StringBuilder();
            LAPI.Data.GestorBBDD oBBDD = LAPI.Data.GestorBBDDFactory.getGestorBBDD();
            System.Collections.Generic.List<LAPI.Data.Model.Deporte> result;

            sql.Append("Select ");
            sql.Append(LAPI.Data.Model.Deporte.Columns);
            sql.Append(" from ");
            sql.Append(LAPI.Data.Model.Deporte.Table);
            sql.Append(" where id_deportes = " + IdDeporte);

            try
            {
                oBBDD.Abrir();
                result = LAPI.Data.Model.Deporte.toModel(oBBDD.Select(sql.ToString()));
                oBBDD.CerrarParcial();
                return result[0];
            }
            catch (Exception ex)
            {
                oBBDD.Cerrar();
                logger.Error(message: ex.Message, exception: ex);
                return null;
            }
        }

        /// <summary>
        /// Método para filtrar una busqueda de Deporte por alguno de estos campos:
        /// <ul>
        /// <li>Descripcion</li>
        /// <li>Identificador</li>
        /// </ul>
        /// </summary>
        /// <param name="filtroBusqueda">Diccionario con el filtro de la búsqueda</param>
        /// <returns>Una colección del modelo con todos los deportes</returns>
        /// <seealso cref="Deporte"/>
        /// <seealso cref="GestorBBDD"/>
        public System.Collections.Generic.List<LAPI.Data.Model.Deporte> ObtenerBusqueda(System.Collections.Hashtable filtroBusqueda)
        {
            System.Text.StringBuilder sql = new System.Text.StringBuilder();
            LAPI.Data.GestorBBDD oBBDD = LAPI.Data.GestorBBDDFactory.getGestorBBDD();
            System.Collections.Generic.List<LAPI.Data.Model.Deporte> result;

            sql.Append("Select ");
            sql.Append(LAPI.Data.Model.Deporte.Columns);
            sql.Append(" from ");
            sql.Append(LAPI.Data.Model.Deporte.Table);
            sql.Append(" where 1=1 ");

            //Añadimos filtros
            if (filtroBusqueda.ContainsKey("descripcion"))
                sql.Append(" and descripcion like '%" + filtroBusqueda["descripcion"].ToString().Replace('*','%') + "%'");

            if (filtroBusqueda.ContainsKey("iddeporte"))
                sql.Append(" and id_deportes like '%" + filtroBusqueda["iddeporte"].ToString().Replace('*', '%') + "%'");

            try
            {
                oBBDD.Abrir();
                result = LAPI.Data.Model.Deporte.toModel(oBBDD.Select(sql.ToString()));
                oBBDD.CerrarParcial();
                return result;
            }
            catch (Exception ex)
            {
                oBBDD.Cerrar();
                logger.Error(message: ex.Message, exception: ex);
                return null;
            }
        }
    #endregion

        #region Comprobaciones
       

#endregion

        #region insert

        /// <summary>
        /// Método para insertar un nuevo Deporte en la base de datos
        /// </summary>
        /// <param name="datosDeporte">Modelo con los datos del Deporte a insertar (previamente validados)</param>
        /// <seealso cref="Deporte"/>
        /// <seealso cref="GestorBBDD"/>
        public void Insertar(LAPI.Data.Model.Deporte datosDeporte)
        {
            System.Text.StringBuilder sql = new System.Text.StringBuilder();
            LAPI.Data.GestorBBDD oBBDD = LAPI.Data.GestorBBDDFactory.getGestorBBDD();
            Int32 result;

            sql.Append("Insert into ");
            sql.Append(LAPI.Data.Model.Deporte.Table);
            sql.Append(" ( ");
            sql.Append(datosDeporte.ToInsertColumns());
            sql.Append(" ) values ( ");
            sql.Append(datosDeporte.ToInsertValues());
            sql.Append(" ) ");            

            try
            {
                oBBDD.Abrir();
                result = oBBDD.Insert(sql.ToString());               
                oBBDD.CerrarParcial();
                if (result != 1)
                    throw new Exception("No se ha insertado el registro: " + datosDeporte);
            }
            catch (Exception ex)
            {
                oBBDD.Cerrar();
                logger.Error(message: ex.Message, exception: ex);
                throw new Exception("No se ha insertado el registro: " + datosDeporte);
            }           
        }

        #endregion

        #region update

        /// <summary>
        /// Método para actualizar los datos 'cambiantes' del Deporte.
        /// </summary>
        /// <param name="datosDeporte">Modelo con los datos del Deporte</param>
        /// <seealso cref="Deporte"/>
        /// <seealso cref="GestorBBDD"/>
        public void Actualizar(LAPI.Data.Model.Deporte datosDeporte)
        {
            System.Text.StringBuilder sql = new System.Text.StringBuilder();
            LAPI.Data.GestorBBDD oBBDD = LAPI.Data.GestorBBDDFactory.getGestorBBDD();
            Int32 result;

            sql.Append("Update ");
            sql.Append(LAPI.Data.Model.Deporte.Table);
            sql.Append(" set ");
            sql.Append(datosDeporte.ToUpdate());
            sql.Append(" where id_deportes =" + datosDeporte.idDeporte);

            try
            {
                oBBDD.Abrir();
                result = oBBDD.Update(sql.ToString());
                oBBDD.CerrarParcial();
                if (result != 1)
                    throw new Exception("No se ha actualizado el registro: " + datosDeporte);
            }
            catch (Exception ex)
            {
                oBBDD.Cerrar();
                logger.Error(message: ex.Message, exception: ex);
                throw new Exception("No se ha actualizado el registro: " + datosDeporte);
            }
        }        

        #endregion

        #region delete

        /// <summary>
        /// Método para eliminar Deporte
        /// </summary>
        /// <param name="datosDeporte">Modelo con los datos del Deporte</param>
        /// <seealso cref="Deporte"/>
        /// <seealso cref="GestorBBDD"/>
        public void Eliminar(LAPI.Data.Model.Deporte datosDeporte)
        {
            System.Text.StringBuilder sql = new System.Text.StringBuilder();
            LAPI.Data.GestorBBDD oBBDD = LAPI.Data.GestorBBDDFactory.getGestorBBDD();
            Int32 result;

            sql.Append("Delete from ");
            sql.Append(LAPI.Data.Model.Deporte.Table);
            sql.Append(" where id_deportes =" + datosDeporte.idDeporte);

            try
            {
                oBBDD.Abrir();
                result = oBBDD.Delete(sql.ToString());
                oBBDD.CerrarParcial();
                if (result != 1)
                    throw new Exception("No se ha eliminado el registro: " + datosDeporte);
            }
            catch (Exception ex)
            {
                oBBDD.Cerrar();
                logger.Error(message: ex.Message, exception: ex);
                throw new Exception("No se ha eliminado el registro: " + datosDeporte);
            }
        }

        #endregion
    }
}
